#!/bin/bash

set -e

DISK=/dev/sda
PART_BOOT=${DISK}1
PART_SWAP=${DISK}2
PART_ROOT=${DISK}3
HOSTNAME="arch"
ROOT_PASSWD="111111"
USER="zhengqijun"
USER_PASSWD="111111"

# Color
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m' # No Color
TIMESTAMP=$(date +"%Y-%m-%d_%H:%M:%S")
LOG_FILE=${TIMESTAMP}.log


function log_print()
{
	local message="$@"
	local file_name=$(basename "${BASH_SOURCE[1]}")
	local line_number=${BASH_LINENO[0]}
	local function_name=${FUNCNAME[1]}
	local ts=$(date +"%Y-%m-%d_%H:%M:%S")
	local output="${GREEN}[${ts}][${file_name}:${line_number}][${function_name}] ${message}${NC}"

	echo -e "${output}" | tee -a "${LOG_FILE}"
}

function log_print_debug()
{
	local message="$@"
	local file_name=$(basename "${BASH_SOURCE[1]}")
	local line_number=${BASH_LINENO[0]}
	local function_name=${FUNCNAME[1]}
	local ts=$(date +"%Y-%m-%d_%H:%M:%S")
	local output="[${ts}][${file_name}:${line_number}][${function_name}] ${message}"

	echo -e "${output}" | tee -a "${LOG_FILE}"
}

function log_print_error()
{
	local message="$@"
	local file_name=$(basename "${BASH_SOURCE[1]}")
	local line_number=${BASH_LINENO[0]}
	local function_name=${FUNCNAME[1]}
	local ts=$(date +"%Y-%m-%d_%H:%M:%S")
	local output="${RED}[${ts}][${file_name}:${line_number}][${function_name}] ${message}${NC}"

	echo -e "${output}" | tee -a "${LOG_FILE}"
}

function arch_logo()
{
	echo "" | tee -a "${LOG_FILE}"
	echo "    █     ▀██▀▀█▄     ▄▄█▀▀▀▄█ ▀██▀  ▀██▀    ▀██▀      ▀██▀ ▀█▄   ▀█▀ ▀██▀  ▀█▀ ▀██▀ ▀█▀" | tee -a "${LOG_FILE}"
	echo "   ███     ██   ██  ▄█▀     ▀   ██    ██      ██        ██   █▀█   █   ██    █    ██ █  " | tee -a "${LOG_FILE}"
	echo "  █  ██    ██▀▀█▀   ██          ██▀▀▀▀██      ██        ██   █ ▀█▄ █   ██    █     ██   " | tee -a "${LOG_FILE}"
	echo " ▄▀▀▀▀█▄   ██   █▄  ▀█▄      ▄  ██    ██      ██        ██   █   ███   ██    █    █ ██  " | tee -a "${LOG_FILE}"
	echo "▄█▄  ▄██▄ ▄██▄  ▀█▀  ▀▀█▄▄▄▄▀  ▄██▄  ▄██▄    ▄██▄▄▄▄▄█ ▄██▄ ▄█▄   ▀█    ▀█▄▄▀   ▄█   ██▄" | tee -a "${LOG_FILE}"
	echo "" | tee -a "${LOG_FILE}"
}

# Step1
function arch_self_check()
{
	log_print "[Step1] start to self check"

	log_print "Check boot mode"
	if [[ -d /sys/firmware/efi/efivars ]]; then
		log_print "Boot to UEFI mode"
	else
		log_print_error "Boot to BIOS mode. Please check boot mode!"
		exit 1
	fi

	log_print "Check network connection"
	ping -c 4 baidu.com
	if [ $? -eq 0 ]; then
		log_print "ping baidu.com success"
	else
		log_print_error "ping baidu.com failed"
		exit 1
	fi

	log_print "[Step1] self check finished"
}

# Step2
function arch_fdisk()
{
	log_print "[Step2] start to fdisk [${DISK}]"

	local swap_total="${1:-+16G}"

	fdisk ${DISK} <<-EOF
		o
		g
		n
		1
		2048
		+512M
		t
		1
		n
		2

		${swap_total}
		t
		2
		19
		n
		3


		t
		3
		20
		w
	EOF

	log_print "[Step2] fdisk [${DISK}] finished"

	fdisk -l | tee -a "${LOG_FILE}"
}

# Step3
function arch_format_mount_part()
{
	log_print "[Step3] start to format and mount partitions"

	# format partitions
	mkfs.fat -F 32 ${PART_BOOT} 2>&1 | tee -a "${LOG_FILE}"
	mkswap ${PART_SWAP} 2>&1 | tee -a "${LOG_FILE}"
	mkfs.ext4 ${PART_ROOT} 2>&1 | tee -a "${LOG_FILE}"

	# mount partitions
	mount ${PART_ROOT} /mnt 2>&1 | tee -a "${LOG_FILE}"
	mount --mkdir ${PART_BOOT} /mnt/boot/efi 2>&1 | tee -a "${LOG_FILE}"
	swapon ${PART_SWAP} 2>&1 | tee -a "${LOG_FILE}"

	log_print "[Step3] format and mount partitions finished"
}

# Step4
function arch_update_sources()
{
	log_print "[Step4] start to update arch sources"

	echo -e 'Server = https://mirrors.tuna.tsinghua.edu.cn/archlinux/$repo/os/$arch' > /etc/pacman.d/mirrorlist | tee -a "${LOG_FILE}"

	pacman -Syy --noconfirm 2>&1 | tee -a "${LOG_FILE}"
	pacman-key --init 2>&1 | tee -a "${LOG_FILE}"
	pacman-key --populate archlinux 2>&1 | tee -a "${LOG_FILE}"
	pacman -Sy archlinux-keyring --noconfirm 2>&1 | tee -a "${LOG_FILE}"

	log_print "[Step4] update arch sources finished"
}

# Step5
function arch_install()
{
	log_print "[Step5] start to install arch"

	pacstrap -K /mnt base base-devel linux linux-firmware sof-firmware vim 2>&1 | tee -a "${LOG_FILE}"

	log_print "[Step5] install arch finished"
}

# Step6
function arch_gen_fstab()
{
	log_print "[Step6] start to generate fstab"

	genfstab -U /mnt > /mnt/etc/fstab 2>&1 | tee -a "${LOG_FILE}"

	log_print "[Step6] generate fstab finished"
}

# Step7
function arch_set_timezone()
{
	log_print "[Step7] start to set timezone in archlinux"

	arch-chroot /mnt /usr/bin/bash -c 'ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime' 2>&1 | tee -a "${LOG_FILE}"
	arch-chroot /mnt /usr/bin/bash -c 'hwclock --systohc' 2>&1 | tee -a "${LOG_FILE}"

	log_print "[Step7] set timezone finished in archlinux"
}

# Step8
function arch_set_locale()
{
	log_print "[Step8] start to set locale in archlinux"

	arch-chroot /mnt /usr/bin/bash -c 'sed -i "s/^#en_US.UTF-8/en_US.UTF-8/" /etc/locale.gen' 2>&1 | tee -a "${LOG_FILE}"
	arch-chroot /mnt /usr/bin/bash -c 'locale-gen' 2>&1 | tee -a "${LOG_FILE}"
	arch-chroot /mnt /usr/bin/bash -c 'echo "LANG=en_US.UTF-8" > /etc/locale.conf' 2>&1 | tee -a "${LOG_FILE}"

	log_print "[Step8] set locale finished in archlinux"
}

# Step9
function arch_set_root_passwd()
{
	log_print "[Step9] start to set root passwd [Name:root Passwd:${ROOT_PASSWD}] in archlinux"

	arch-chroot /mnt /usr/bin/bash -c "echo -e '${ROOT_PASSWD}\n${ROOT_PASSWD}' | passwd root" 2>&1 | tee -a "${LOG_FILE}"

	log_print "[Step9] set root passwd [${ROOT_PASSWD}] finished in archlinux"
}

# Step10
function arch_set_hostname()
{
	log_print "[Step10] start to set hostname [${HOSTNAME}] in archlinux"

	arch-chroot /mnt /usr/bin/bash -c "echo '${HOSTNAME}' > /etc/hostname" 2>&1 | tee -a "${LOG_FILE}"

	log_print "[Step10] set hostname [${HOSTNAME}] finished in archlinux"
}

# Step11
function arch_set_network()
{
	log_print "[Step11] start to set network in archlinux"

	pacstrap -K /mnt networkmanager 2>&1 | tee -a "${LOG_FILE}"
	arch-chroot /mnt /usr/bin/bash -c 'systemctl enable NetworkManager.service' 2>&1 | tee -a "${LOG_FILE}"

	log_print "[Step11] set network finished in archlinux"
}

# Step12
function arch_set_user()
{
	log_print "[Step12] start to set user [Name:${USER} Passwd:${USER_PASSWD}] in archlinux"

	pacstrap -K /mnt sudo 2>&1 | tee -a "${LOG_FILE}"
	arch-chroot /mnt /usr/bin/bash -c 'groupadd sudo' 2>&1 | tee -a "${LOG_FILE}"
	arch-chroot /mnt /usr/bin/bash -c "useradd -m -G wheel,sudo '${USER}'" 2>&1 | tee -a "${LOG_FILE}"
	arch-chroot /mnt /usr/bin/bash -c "echo -e '${USER_PASSWD}\n${USER_PASSWD}' | passwd '${USER}'" 2>&1 | tee -a "${LOG_FILE}"
	arch-chroot /mnt /usr/bin/bash -c 'sed -i "s/^# %wheel ALL=(ALL:ALL) ALL/%wheel ALL=(ALL:ALL) ALL/" /etc/sudoers' 2>&1 | tee -a "${LOG_FILE}"
	arch-chroot /mnt /usr/bin/bash -c 'sed -i "s/^# %sudo\tALL=(ALL:ALL) ALL/%sudo ALL=(ALL:ALL) ALL/" /etc/sudoers' 2>&1 | tee -a "${LOG_FILE}"

	log_print "[Step12] set user [Name:${USER} Passwd:${USER_PASSWD}] finished in archlinux"
}

# Step13
function arch_set_bootloader()
{
	log_print "[Step13] start to set bootloader in archlinux"

	pacstrap -K /mnt grub efibootmgr 2>&1 | tee -a "${LOG_FILE}"
	local cpu_vendor=$(cat /proc/cpuinfo | grep 'vendor_id' | uniq | awk '{print $3}')
	if [[ "${cpu_vendor}" == "GenuineIntel" ]]; then
		log_print "install intel-ucode in archlinux"
		pacstrap -K /mnt intel-ucode 2>&1 | tee -a "${LOG_FILE}"
	elif [[ "${cpu_vendor}" = "AuthenticAMD" ]]; then
		log_print "install amd-ucode in archlinux"
		pacstrap -K /mnt amd-ucode 2>&1 | tee -a "${LOG_FILE}"
	else
		log_print "unknown CPU vendor [${cpu_vendor}] in archlinux !"
	fi

	arch-chroot /mnt /usr/bin/bash -c 'grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=GRUB' 2>&1 | tee -a "${LOG_FILE}"
	arch-chroot /mnt /usr/bin/bash -c 'grub-mkconfig -o /boot/grub/grub.cfg' 2>&1 | tee -a "${LOG_FILE}"

	log_print "[Step13] set bootloader finished in archlinux"
}

# Step14
function arch_umount_finished()
{
	log_print "[Step14] start to umount finished"

	umount -R /mnt | tee -a "${LOG_FILE}"

	log_print "[Step14] umount finished, waiting reboot"
}

function main()
{
	arch_logo
	arch_self_check
	arch_fdisk
	arch_format_mount_part
	arch_update_sources
	arch_install
	arch_gen_fstab
	arch_set_timezone
	arch_set_locale
	arch_set_root_passwd
	arch_set_hostname
	arch_set_network
	arch_set_user
	arch_set_bootloader
	arch_umount_finished
	arch_logo

	log_print "The installation of archlinux has been completed. Have a good time!"
}

main

# EOF

